using UnityEngine;
using System.Collections;
using System.Collections.Generic;



public class GameMsgScript : MonoBehaviour {
	public const float SCREEN_HEIGHT = 12.0f;
	public const float SCREEN_WIDTH = 12.0f * 960.0f / 640.0f;
	
	
	public enum SphereType
	{
		Type_Red,
		Type_Blue,
		Type_Yellow,
		Type_Grey,
		Type_Num,
	}
	
	
	public enum GridType
	{
		Type_White,
		Type_lack,
		Type_Num,
	}
	
	public enum GameMode
	{
		Mode_Normal,
		Mode_Monster,
		Mode_Num,
	}
	
	public enum GameState
	{
		State_None,
		State_Mode_Select,
		State_Init_Mode,
		State_Playing,
		State_End,
		State_Num,
	}
	
	

	
	public class FireEvent : System.EventArgs
	{
		public Vector3 inPutPosition;
		public GameMode gameMode;
	}
	
	[System.Serializable]	
	public class SphereTypeConfig
	{
		public SphereType 	sphereType;
		public Color		color;
	}
	[System.Serializable]
	public class GridTypeCinfig
	{
		public GridType gridType;
		public Material gridMaterial;
		public Texture2D  gridDefaultTex;
		public Texture2D  gridFocusTex;
	}
	
	
	void OnGUI() {
		
		if ( curState == GameMsgScript.GameState.State_Mode_Select )
		{
			if (GUI.Button(new Rect(10, 10, 70, 30), "Normal!"))
			{
				StartCoroutine( WaitStart(GameMode.Mode_Normal) );
			}
			else if (GUI.Button(new Rect(10, 40, 70, 30), "Monster!"))
			{
				StartCoroutine( WaitStart(GameMode.Mode_Monster) );
			}
		}
		else if ( curState == GameMsgScript.GameState.State_Playing	)
		{
			foreach( HudBaseScript script in hudList )
			{
				script.Render();
			}
		}
		else
		{
			if (GUI.Button(new Rect(10, 10, 150, 100), "Again!"))
			{
				StartCoroutine( ReStart() );
			}
		}
        
    }
	
	IEnumerator WaitStart( GameMode gameMode )
	{
		yield return null;
		FireEvent fe = new FireEvent();
		fe.gameMode = gameMode;
		SwithState( GameState.State_Init_Mode, fe as System.EventArgs );
	}
	
	IEnumerator ReStart()
	{
		yield return null;
		curGameMode.SwithState( GameModeBaseScript.ModeState.State_None, null );
		SwithState( GameState.State_Playing, null );
		
	}
	

	
	// Use this for initialization
	void Start () {
		InitStateMechanic();
		InitDate();
		//InitLevel();
		curState = GameMsgScript.GameState.State_Mode_Select;
		
	}
	
	
	public void SwitchMode( GameMode gameMode )
	{
		/*switch( (int)gameMode )
		{
		case (int)GameMode.Mode_Normal:
			{
				curGameMode = new NormalModeScript() as GameModeBaseScript;
			}
		}*/
		if ( gameMode == GameMode.Mode_Normal )
		{
			curGameMode = new NormalModeScript() as GameModeBaseScript;
		}
		else if ( gameMode == GameMode.Mode_Monster )
		{
			curGameMode = new MonsterModeScript() as GameModeBaseScript;
		}
		
		curGameMode.SetDifficult(1);
		curGameMode.gameMsg = this;
		curGameMode.screenMsg = screenMsg;
		curGameMode.Init();
	}
	
	// Update is called once per frame
	void Update () {
		if ( curState == GameMsgScript.GameState.State_Playing )
			curGameMode.Update();
	}
	
	void LateUpdate() {
        if ( curState == GameMsgScript.GameState.State_Playing )
		{
			Ray ray =  Camera.mainCamera.ScreenPointToRay (InputScript.GetMousePosition()); 
			if( InputScript.MouseButtonIsUp() )
			{
				curGameMode.Operate( ray, true );
			}
			else
			{
				curGameMode.Operate( ray, false );
			}
		}
    }
	
	public void InitDate()
	{
		scoreText = GetComponent<GUIText>();
		TimeBarScript timeScript = new TimeBarScript();
		hudList.Add( timeScript );
		timeScript.GameMsg = this;
		screenMsg.Init();
		
	}
	
	public void DeleteDate()
	{
	
	}
	
	public void InitLevel( GameMode gameMode )
	{
		SwitchMode( gameMode );
	}
	
	public void InitStateMechanic()
	{
		stateMechanics[(int)GameState.State_Mode_Select] = new StateMechanicScript( (int)GameState.State_Num,
			new StateMechanicScript.MyEventHandler( this.SwitchToModeSelect ),
			new StateMechanicScript.MyEventHandler( this.BreakModeSelect ) );
		stateMechanics[(int)GameState.State_Mode_Select].SetStateChange( (int)GameState.State_Init_Mode, true );
		
		
		stateMechanics[(int)GameState.State_Init_Mode] = new StateMechanicScript( (int)GameState.State_Num,
			new StateMechanicScript.MyEventHandler( this.SwitchToInitMode ),
			new StateMechanicScript.MyEventHandler( this.BreakInitMode ) );
		stateMechanics[(int)GameState.State_Init_Mode].SetStateChange( (int)GameState.State_Playing, true );
		
		stateMechanics[(int)GameState.State_Playing] = new StateMechanicScript( (int)GameState.State_Num,
			new StateMechanicScript.MyEventHandler( this.SwitchToPlaying ),
			new StateMechanicScript.MyEventHandler( this.BreakPlaying ) );
		stateMechanics[(int)GameState.State_Playing].SetStateChange( (int)GameState.State_End, true );
		
	
		stateMechanics[(int)GameState.State_End] = new StateMechanicScript( (int)GameState.State_Num,
			new StateMechanicScript.MyEventHandler( this.SwitchToEnd ),
			new StateMechanicScript.MyEventHandler( this.BreakEnd ) );
		stateMechanics[(int)GameState.State_End].SetStateChange( (int)GameState.State_Playing, true );
	}
	
	public bool SwithState( GameState changeToState, System.EventArgs e )
	{
		if ( stateMechanics[ (int)curState ].CanChangeTo( (int)changeToState ) )
		{
			stateMechanics[ (int)curState ].breakFunction( this, e );
			stateMechanics[ (int)changeToState ].stateFunction( this, e );
			return true;
		}
		return false;
	}
	
			
	public void SwitchToModeSelect( object sender, System.EventArgs e )
	{
		curState = GameMsgScript.GameState.State_Mode_Select;
	}
		
	public void BreakModeSelect( object sender, System.EventArgs e )
	{
		
	}
	
	public void SwitchToInitMode( object sender, System.EventArgs e )
	{
		curState = GameMsgScript.GameState.State_Init_Mode;
		InitDate();
		FireEvent fe = e as FireEvent;
		InitLevel( fe.gameMode);
		SwithState( GameState.State_Playing, null );
		
	}
		
	public void BreakInitMode( object sender, System.EventArgs e )
	{
		
	}
	
	public void SwitchToPlaying(  object sender, System.EventArgs e )
	{
		curState = GameMsgScript.GameState.State_Playing;
		curGameMode.SwithState( GameModeBaseScript.ModeState.State_Idle, null );
	}
	
	public void BreakPlaying(  object sender, System.EventArgs e )
	{
		//DeleteDate();
		//InitLevel();
		
	}
	
	public void SwitchToEnd(  object sender, System.EventArgs e )
	{
		curState = GameMsgScript.GameState.State_End;
		//SwithState( GameState.State_Idle, null );
	}
	
	public void BreakEnd(  object sender, System.EventArgs e )
	{
		//DeleteDate();
		//InitLevel();
		
	}
	
	
	
	public void SetScoreTex( int score )
	{
		scoreText.text = score.ToString();
	}
	
	public GUIText scoreText;
	
	public SphereTypeConfig[] sphereTypeConfig ;
	public GridTypeCinfig[]   gridTypeConfig;
	List<HudBaseScript> hudList = new List<HudBaseScript>();
	
	public ScreenMsgScript screenMsg = new ScreenMsgScript();
	
	public GameModeBaseScript curGameMode;

	
	public StateMechanicScript[]	stateMechanics = new StateMechanicScript[(int)GameState.State_Num];
	public GameState		  curState = GameMsgScript.GameState.State_None;
	
	
}
